/*************************************************************************
	> File Name: 006.重载->运算符.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 五  1/ 7 11:06:00 2022
 ************************************************************************/

#include <iostream>
using namespace std;

class Point {
public :
    Point();
    Point(int x, int y);
    //类内重载运算符+，只需要传入一个参数
    //因为this指针指向的对象代表了+左边的参数，而传入的参数a代表+右边的参数
    Point operator+(const Point &a);
    //重载+=运算符
    Point &operator+=(int);
    //重载[]运算符
    int operator[](string s);
    int getX() const { return x; }
    int getY() const { return y; }
private :
    friend Point operator+(const Point &a, const Point &b);
    friend ostream &operator<<(ostream &out, const Point &p);
    int x, y;
};

class PPoint {
public :
    PPoint(Point* p) : p(p) {}
    Point* operator->() { return p; } //->运算符重载通常返回指针
private:
    Point* p;
};

Point::Point() : Point(0, 0) {}
Point::Point(int x, int y) : x(x), y(y) {}
int Point::operator[](string s) {
    if (s == "x") return x;
    if (s == "y") return y;
    return 0;
}
Point &Point::operator+=(int n) {
    x += n, y += n;
    return *this;
}

//类内重载+
Point Point::operator+(const Point &rhs) {
    cout << "inner operator+" << endl;
    Point c(x + rhs.x, y + rhs.y);
    return c;
}

//类外重载+
Point operator+(const Point &lhs, const Point &rhs) {
    cout << "outer operator+" << endl;
    Point c(lhs.x + rhs.x, lhs.y + rhs.y);
    return c;
}

ostream &operator<<(ostream &out, const Point &rhs) {
    out << "(" << rhs.x << ", " << rhs.y << ")";
    return out;
}

int main() {
    Point p1(3, 4);
    Point p2(7, 9);
    cout << p1["x"] << endl; //3
    cout << p1["y"] << endl; //4
    Point p3 = p1 + p2; //inner operator+
    cout << p1 << endl; //(3, 4)
    cout << p2 << endl; //(7, 9)
    cout << p3 << endl; //(10, 13)

    p1 += 2; //给p1的x和y各+2
    cout << p1 << endl; //(5, 6)

    PPoint p = &p1; //调用了转换构造函数
    cout << p->getX() << " " << p->getY() << endl; //5 6
    return 0;
}
